﻿using System.Collections.Generic;
using ApplicationLibrary;
using ApplicationLibrary.DBManager;
using ApplicationLibrary.ExtendedControls;
using ApplicationLibrary.SqlConnector;
using Clothes.Items.ModuleData;
using System.Windows.Forms;
using System.Drawing;

namespace Clothes.Items.Forms
{
    public partial class Categories : ApplicationLibrary.DBManager.DocumentForm
    {
        private BindableOject<string> Code = null;
        private BindableOject<int> ID = null;
        private EnumsManager<DocType> eDocTypeManager = new EnumsManager<DocType>(Properties.Resources.ResourceManager);
        private RUCategoriesByFather ruCategories = null;
        private DUCategories duCategories = null;
        private string NewFather = string.Empty;

        public Categories()
            : base("Categories")
        {
            InitializeComponent();
        }

        #region Virtual Method

        protected override IRadarParameters GetKeyFromDocument()
        {
            return new RadarCategoriesParam(Code.Value);
        }

        protected override void OnAttachData()
        {
            dbManager = new dbmanagerCategories("categoriesForm", new RadarCategories(), this);
            dbManager.AddMaster(this, CL_Categories.Name, true);

            Code = new BindableOject<string>();
            ID = new BindableOject<int>();
            ID.AttachCounterType(Counters.Categories.Int(), GlobalInfo.CurrentDate, null);

            cbbFather.AttachDataReader<string>(new RUCategories(), CL_Categories.Code, CL_Categories.Description, true);

            duCategories = new DUCategories(true);
            ruCategories = new RUCategoriesByFather(true);
        }

        protected override void OnBindData()
        {
            BindObject(Code, CL_Categories.Code);
            BindControl(cbbFather, CL_Categories.CodeFather, "SelectedValue", NullValue.NotSet);
            BindControl(txtDescription, CL_Categories.Description);
            BindControl(ckbEnableModify);

            BindCounter(ID);
        }

        protected override void OnDisableControlsForEdit()
        {
            trvCat.Enabled = false;
            cbbFather.Enabled = ckbEnableModify.Checked;
            base.OnDisableControlsForEdit();
        }

        protected override void OnDisableControlsForNew()
        {
            trvCat.Enabled = false;
            cbbFather.Enabled = ckbEnableModify.Checked;
            base.OnDisableControlsForNew();
        }
        protected override void OnShown(System.EventArgs e)
        {
            base.OnShown(e);
            trvCat.LoadCategories();
        }

        protected override bool OnAfterAddNew()
        {
            Code.Value = ConvertToString(ID.Value);
            
            return base.OnAfterAddNew();
        }

        protected override bool OnAfterSave()
        {
            return base.OnAfterSave();
        }

        protected override bool OnBeforeDelete()
        {
            System.Windows.Forms.DialogResult res = System.Windows.Forms.DialogResult.Yes;

            if (ruCategories.Find(Code.Value) && ruCategories.Count > 0)
            {
                res = MessageBox.Show("Cancello anche i figli", "Attenzione", MessageBoxButtons.YesNoCancel);
                if (res == System.Windows.Forms.DialogResult.Yes)
                    DeleteChild();
                else
                    AttachChild();
            }
            return true;
        }

        private void AttachChild()
        {
            for (int t = 0; t < ruCategories.Count; t++)
            {
                ruCategories.SetValue<string>(CL_Categories.CodeFather, t, cbbFather.GetValue<string>());
                ruCategories.Update();
            }
        }

        private void DeleteChild()
        {
            List<string> child = new List<string>();
            child.Add(Code.Value);

            do
            {
                for (int i = child.Count - 1; i >= 0; i--)
                {
                    ruCategories.Find(child[i]);
                    child.RemoveAt(i);
                    for (int t = 0; t < ruCategories.Count; t++)
                    {
                        child.Add(ruCategories.GetValue<string>(CL_Categories.Code, t));
                        ruCategories.Delete(t);
                    }
                    ruCategories.Update();
                }
            }
            while (child.Count > 0);

            trvCat.LoadCategories();
        }

        protected override void OnPrepareAuxData()
        {
            if (!NewFather.IsEmpty())
            {
                cbbFather.SelectedValue = NewFather;
                NewFather = string.Empty;
            }
            trvCat.Code = Code.Value;
            trvCat.LoadCategories();

            base.OnPrepareAuxData();
        }

        protected override void FocusOnNew()
        {
           txtDescription.Focus();
        }

        protected override void OnValidateControl()
        {
            //Code.Value = ConvertToString(ID.Value);
            //Code.ResumeBinding();
            base.OnValidateControl();
            trvCat.Enabled = true;
        }
        #endregion

        private static string ConvertToString(int value)
        {
            string convert = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            string converted = "";

            int bbase = (int)convert.Length;

            while (value > bbase)
            {
                int rest = value % bbase;
                value = value / bbase;
                converted = convert.Substring((int)rest, 1) + converted;
            }
            converted = convert.Substring((int)value, 1) + converted;

            return string.Format("{0,2}",converted);
        }

        private void tsmiAdd_Click(object sender, System.EventArgs e)
        {
            if (trvCat.SelectedNode == null)
                return;

            NewFather = trvCat.SelectedNode.Name;
            ToolbarEvent(ToolbarEventKind.New);
        }

        private void tsmiEdit_Click(object sender, System.EventArgs e)
        {
            if (trvCat.SelectedNode == null)
                return;

            FindRecord(new RadarCategoriesParam(trvCat.SelectedNode.Name));
            ToolbarEvent(ToolbarEventKind.Edit);
        }

        private void tsmiDelete_Click(object sender, System.EventArgs e)
        {
            if (trvCat.SelectedNode == null)
                return;

            FindRecord(new RadarCategoriesParam(trvCat.SelectedNode.Name));
            ToolbarEvent(ToolbarEventKind.Delete);
        }

        private void trvCat_DragDrop(object sender, DragEventArgs e)
        {
            // Retrieve the client coordinates of the drop location.
            Point targetPoint = trvCat.PointToClient(new Point(e.X, e.Y));

            // Retrieve the node at the drop location.
            TreeNode targetNode = trvCat.GetNodeAt(targetPoint);

            // Retrieve the node that was dragged.
            TreeNode draggedNode = (TreeNode)e.Data.GetData(typeof(TreeNode));

            // Confirm that the node at the drop location is not 
            // the dragged node or a descendant of the dragged node.
            if (!draggedNode.Equals(targetNode) && !ContainsNode(draggedNode, targetNode))
            {
                if (draggedNode.Parent == targetNode)
                {
                    MessageBox.Show("Stesso padre");
                    return;
                }

                if (draggedNode.Nodes.Count > 0)
                {
                    DialogResult res = MessageBox.Show("Verranno spostati anche i figli.\nProcedo ?", "Scegli", MessageBoxButtons.YesNo, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1);
                    if (res == System.Windows.Forms.DialogResult.No)
                        return;
                }
            }

            duCategories.Find(draggedNode.Name);
            duCategories.SetValue<string>(CL_Categories.CodeFather, targetNode.Name);
            duCategories.Update();
            draggedNode.Remove();
            targetNode.Nodes.Add(draggedNode);
            trvCat.MovedCode(draggedNode);
        }

        private void trvCat_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = e.AllowedEffect;
        }

        private void trvCat_DragOver(object sender, DragEventArgs e)
        {
            Point targetPoint = trvCat.PointToClient(new Point(e.X, e.Y));

            // Select the node at the mouse position.
            trvCat.SelectedNode = trvCat.GetNodeAt(targetPoint);
            if (trvCat.SelectedNode != null)
                trvCat.SelectedNode.Expand();
        }

        void trvCat_ItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
                DoDragDrop(e.Item, DragDropEffects.Move);
        }

        private bool ContainsNode(TreeNode node1, TreeNode node2)
        {
            // Check the parent node of the second node.
            if (node2.Parent == null) return false;
            if (node2.Parent.Equals(node1)) return true;

            // If the parent node is not null or equal to the first node, 
            // call the ContainsNode method recursively using the parent of 
            // the second node.
            return ContainsNode(node1, node2.Parent);
        }

        private void trvCat_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                Point targetPoint = trvCat.PointToClient(new Point(e.X, e.Y));
                if (trvCat.GetNodeAt(e.X, e.Y) != null)
                    trvCat.SelectedNode = trvCat.GetNodeAt(e.X, e.Y);
            }
        }

        private void ckbEnableModify_CheckedChanged(object sender, System.EventArgs e)
        {
            cbbFather.Enabled = ckbEnableModify.Checked;
        }

        private void trvCat_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            FindRecord(new RadarCategoriesParam(e.Node.Name));
        }
    }

    #region DbManager dbmanagerMasters

    /// <summary>
    /// Classe derivata per gestioni particolari
    /// </summary>
    internal class dbmanagerCategories : DBManager
    {
        public dbmanagerCategories(string name, RadarForm radar, DocumentForm document)
            : base(name, radar, document)
        { }

        protected override void dAdapter_MasterRowUpdating(object sender, SqlABRowUpdatingEventArgs e)
        {
            base.dAdapter_MasterRowUpdating(sender, e);
        }

        protected override string CreateMasterQuery()
        {
            this.Table = new CL_Categories();
            QueryBuilder qB = new QueryBuilder();
            qB.AddSelect();
            qB.AddFrom(this.Table);
            qB.AddCompare(CL_Categories.Code, "@p1");

            return qB.Query;
        }

        protected override List<SqlABParameter> CreateMasterParam()
        {
            List<SqlABParameter> PList = new List<SqlABParameter>();

            SqlABParameter sParam1 = new SqlABParameter("@p1", CL_Categories.Code) { Value = CL_Categories.Code.DefaultValue };
            PList.Add(sParam1);
            return PList;
        }

        protected override void SetParameters(ApplicationLibrary.ExtendedControls.IRadarParameters key, DBCollection collection)
        {
            collection.Parameter[0].Value = key[0];
        }
    }

    #endregion



}
